<html lang="zh-CN"><head><meta charset="UTF-8"><style>.nodata  main {width:1000px;margin: auto;}</style></head><body class="nodata " style=""><div class="main_father clearfix d-flex justify-content-center " style="height:100%;"> <div class="container clearfix " id="mainBox"><main><div class="blog-content-box">
<div class="article-header-box">
<div class="article-header">
<div class="article-title-box">
<h1 class="title-article" id="articleContentId">(B卷,100分)- 最长公共后缀（Java & JS & Python & C）</h1>
</div>
</div>
</div>
<div id="blogHuaweiyunAdvert"></div>

        <div id="article_content" class="article_content clearfix">
        <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css">
        <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-044f2cf1dc.css">
                <div id="content_views" class="htmledit_views">
                    <h4 id="main-toc">题目描述</h4> 
<p>编写一个函数来查找字符串数组中的最长公共后缀&#xff1b;</p> 
<p>如果不存在公共后缀&#xff0c;返回固定字符串&#xff1a; &#64;Zero。</p> 
<p></p> 
<p>补充说明&#xff1a;</p> 
<ol><li>字符串长度范围&#xff1a;[2, 1000]</li><li>字符串中字符取值范围为[1, 126]</li></ol> 
<p></p> 
<h4 id="%E8%BE%93%E5%85%A5%E6%8F%8F%E8%BF%B0">输入描述</h4> 
<p>无</p> 
<p></p> 
<h4 id="%E8%BE%93%E5%87%BA%E6%8F%8F%E8%BF%B0">输出描述</h4> 
<p>无</p> 
<p></p> 
<h4 id="%E7%94%A8%E4%BE%8B">用例</h4> 
<table border="1" cellpadding="1" cellspacing="1" style="width:500px;"><tbody><tr><td style="width:86px;">输入</td><td style="width:412px;">[&#34;abc&#34;,&#34;bbc&#34;,&#34;c&#34;]</td></tr><tr><td style="width:86px;">输出</td><td style="width:412px;">&#34;c&#34;</td></tr><tr><td style="width:86px;">说明</td><td style="width:412px;">返回公共后缀: c</td></tr></tbody></table> 
<table border="1" cellpadding="1" cellspacing="1" style="width:500px;"><tbody><tr><td style="width:86px;">输入</td><td style="width:412px;">[&#34;aa&#34;,&#34;bb&#34;,&#34;cc&#34;]</td></tr><tr><td style="width:86px;">输出</td><td style="width:412px;">&#34;&#64;Zero&#34;</td></tr><tr><td style="width:86px;">说明</td><td style="width:412px;">不存在公共后缀&#xff0c;返回固定结果: &#64;Zero</td></tr></tbody></table> 
<p></p> 
<h4 id="%E9%A2%98%E7%9B%AE%E8%A7%A3%E6%9E%90">题目解析</h4> 
<p>本题应该是采用核心代码模式&#xff0c;非ACM模式&#xff0c;因此不需要我们处理输入输出。</p> 
<p>下面代码仍然以ACM模式实现&#xff0c;但是会将输入输出处理 和 核心代码 分离。考试时&#xff0c;只需要写出核心代码即可。</p> 
<p></p> 
<p>关于核心代码实现&#xff0c;我的思路如下</p> 
<p>假设输入的字符串数组为strs&#xff0c;则可以&#xff1a;</p> 
<ol><li>将strs[0]假设为最长公共后缀suffx</li><li>之后&#xff0c;再找出suffix和strs[1]的最长公共后缀&#xff0c;并覆盖给suffix&#xff0c;按此逻辑继续找出suffix和其他strs[i]的最长公共后缀</li></ol> 
<p>当然&#xff0c;在上面过程中&#xff0c;一旦发现suffix &#61;&#61; “”&#xff0c;即最长公共后缀是空串&#xff0c;则可以直接返回&#64;Zero。</p> 
<p>否则&#xff0c;返回suffix。</p> 
<p></p> 
<h4 id="%E7%AE%97%E6%B3%95%E6%BA%90%E7%A0%81">JS算法源码</h4> 
<pre><code class="language-javascript">/* JavaScript Node ACM模式 控制台输入获取 */
const readline &#61; require(&#34;readline&#34;);

const rl &#61; readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on(&#34;line&#34;, (line) &#61;&gt; {
  const strs &#61; JSON.parse(line);
  console.log(getResult(strs));
});

function getResult(strs) {
  // 假设第0个字符串就是最长公共后缀
  let suffix &#61; strs[0];

  // 从第1个字符串开始&#xff0c;求解和最长公共后缀suffix的最长公共后置
  for (let i &#61; 1; i &lt; strs.length; i&#43;&#43;) {
    suffix &#61; getLCS(suffix, strs[i]);

    // 如果最长公共后缀为“”,则直接返回&#34;&#64;Zero&#34;
    if (suffix &#61;&#61; &#34;&#34;) return &#34;&#64;Zero&#34;;
  }

  return suffix;
}

/**
 *  求两个字符串的最长公共后缀
 * &#64;param {*} s1
 * &#64;param {*} s2
 * &#64;returns 最长公共后缀
 */
function getLCS(s1, s2) {
  // 如果尾字符不同&#xff0c;则没有公共后缀
  if (s1.at(-1) !&#61; s2.at(-1)) return &#34;&#34;;

  // 最长公共后缀的长度上限是&#xff1a;两个字符串中较短的那个的长度值
  const maxLen &#61; Math.min(s1.length, s2.length);

  // 开始逐位比较
  for (let i &#61; -2; i &gt;&#61; -maxLen; i--) {
    // 如果某位对应字符不同
    if (s1.at(i) !&#61; s2.at(i)) {
      // 则该位后面的就是最长公共后缀
      return s1.slice(i &#43; 1);
    }
  }

  // 如果比较完了&#xff0c;都没有发现对应位不同字符&#xff0c;则说明&#xff0c;两个字符串中较短者本身就是最长公共后缀
  return s1.slice(-maxLen);
}
</code></pre> 
<p></p> 
<h4>Java算法源码</h4> 
<pre><code class="language-java">import java.util.Arrays;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc &#61; new Scanner(System.in);

    String line &#61; sc.nextLine();
    String[] strings &#61;
        Arrays.stream(line.substring(1, line.length() - 1).split(&#34;,&#34;))
            .map(s -&gt; s.substring(1, s.length() - 1))
            .toArray(String[]::new);

    System.out.println(getResult(strings));
  }

  public static String getResult(String[] strings) {
    // 假设第0个字符串就是最长公共后缀
    String suffix &#61; strings[0];

    // 从第1个字符串开始&#xff0c;求解和最长公共后缀suffix的最长公共后置
    for (int i &#61; 1; i &lt; strings.length; i&#43;&#43;) {
      suffix &#61; getLCS(suffix, strings[i]);

      // 如果最长公共后缀为“”,则直接返回&#34;&#64;Zero&#34;
      if (&#34;&#34;.equals(suffix)) return &#34;&#64;Zero&#34;;
    }

    return suffix;
  }

  /**
   * 求两个字符串的最长公共后缀
   *
   * &#64;param s1 字符串1
   * &#64;param s2 字符串2
   * &#64;return 两个字符串的最长公共后缀
   */
  public static String getLCS(String s1, String s2) {
    // 如果尾字符不同&#xff0c;则没有公共后缀
    if (charAt(s1, -1) !&#61; charAt(s2, -1)) return &#34;&#34;;

    // 最长公共后缀的长度上限是&#xff1a;两个字符串中较短的那个的长度值
    int maxLen &#61; Math.min(s1.length(), s2.length());

    // 开始逐位比较
    for (int i &#61; -2; i &gt;&#61; -maxLen; i--) {
      // 如果某位对应字符不同,则该位后面的就是最长公共后缀
      if (charAt(s1, i) !&#61; charAt(s2, i)) return s1.substring(s1.length() &#43; i &#43; 1);
    }

    // 如果比较完了&#xff0c;都没有发现对应位不同字符&#xff0c;则说明&#xff0c;两个字符串中较短者本身就是最长公共后缀
    return s1.substring(s1.length() - maxLen);
  }

  // 负数索引找字符&#xff0c;比如索引-1  等价于 索引s.length-1
  public static char charAt(String s, int negativeIndex) {
    return s.charAt(s.length() &#43; negativeIndex);
  }
}
</code></pre> 
<p></p> 
<h4>Python算法源码</h4> 
<pre><code class="language-python"># 输入获取
strs &#61; eval(input())


def getLCS(s1, s2):
    &#34;&#34;&#34;
    求两个字符串的最长公共后缀
    :param s1:
    :param s2:
    :return: 最长公共后缀
    &#34;&#34;&#34;
    if s1[-1] !&#61; s2[-1]:
        return &#34;&#34;  # 如果尾字符不同&#xff0c;则没有公共后缀

    # 最长公共后缀的长度上限是&#xff1a;两个字符串中较短的那个的长度值
    maxLen &#61; min(len(s1), len(s2))

    # 开始逐位比较
    for i in range(-2, -maxLen - 1, -1):
        if s1[i] !&#61; s2[i]:
            # 如果某位对应字符不同, 则该位后面的就是最长公共后缀
            return s1[i &#43; 1:]

    # 如果比较完了&#xff0c;都没有发现对应位不同字符&#xff0c;则说明&#xff0c;两个字符串中较短者本身就是最长公共后缀
    return s1[-maxLen:]


# 核心代码
def getResult():
    # 假设第0个字符串就是最长公共后缀
    suffix &#61; strs[0]

    # 从第1个字符串开始&#xff0c;求解和最长公共后缀suffix的最长公共后置
    for i in range(1, len(strs)):
        suffix &#61; getLCS(suffix, strs[i])

        # 如果最长公共后缀为“”,则直接返回&#34;&#64;Zero&#34;
        if suffix &#61;&#61; &#34;&#34;:
            return &#34;&#64;Zero&#34;

    return suffix


# 算法调用
print(getResult())
</code></pre> 
<h4>C算法源码</h4> 
<pre><code class="language-cpp">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

#define MIN(a, b) ((a) &gt; (b) ? (a) : (b))
#define MAX_SIZE 1001

char *getLCS(char *s1, char *s2);
char *getResult(char ss[][MAX_SIZE], int ss_size);

int main() {
    char s[MAX_SIZE];
    scanf(&#34;%s&#34;, s);

    char ss[MAX_SIZE][MAX_SIZE];
    int ss_size &#61; 0;

    char *delimiter &#61; &#34;\\[\\]\\,\&#34;&#34;;

    char *token &#61; strtok(s, delimiter);
    while (token !&#61; NULL) {
        strcpy(ss[ss_size&#43;&#43;], token);
        token &#61; strtok(NULL, delimiter);
    }

    puts(getResult(ss, ss_size));

    return 0;
}

char *getResult(char ss[][MAX_SIZE], int ss_size) {
    // 假设第0个字符串就是最长公共后缀
    char *suffix &#61; ss[0];

    // 从第1个字符串开始&#xff0c;求解和最长公共后缀suffix的最长公共后置
    for (int i &#61; 1; i &lt; ss_size; i&#43;&#43;) {
        strcpy(suffix, getLCS(suffix, ss[i]));

        // 如果最长公共后缀为“”,则直接返回&#34;&#64;Zero&#34;
        if (strcmp(&#34;&#34;, suffix) &#61;&#61; 0) return &#34;&#64;Zero&#34;;
    }

    return suffix;
}

/*!
 * 求两个字符串的最长公共后缀
 * &#64;param s1
 * &#64;param s2
 * &#64;return 最长公共后缀
 */
char *getLCS(char *s1, char *s2) {
    unsigned long long len1 &#61; strlen(s1);
    unsigned long long len2 &#61; strlen(s2);

    // 如果尾字符不同&#xff0c;则没有公共后缀
    if (s1[len1 - 1] !&#61; s2[len2 - 1]) return &#34;&#34;;

    // 最长公共后缀的长度上限是&#xff1a;两个字符串中较短的那个的长度值
    int maxLen &#61; MIN(len1, len2);

    // 开始逐位比较
    for (int i &#61; -2; i &gt;&#61; -maxLen; i--) {
        // 如果某位对应字符不同
        if (s1[len1 &#43; i] !&#61; s2[len2 &#43; i]) {
            // 则该位后面的就是最长公共后缀
            return s1 &#43; len1 &#43; i &#43; 1;
        }
    }

    // 如果比较完了&#xff0c;都没有发现对应位不同字符&#xff0c;则说明&#xff0c;两个字符串中较短者本身就是最长公共后缀
    return s1 &#43; len1 - maxLen;
}</code></pre> 
<p></p>
                </div>
        </div>
        <div id="treeSkill"></div>
        <div id="blogExtensionBox" style="width:400px;margin:auto;margin-top:12px" class="blog-extension-box"></div>
    <script>
  $(function() {
    setTimeout(function () {
      var mathcodeList = document.querySelectorAll('.htmledit_views img.mathcode');
      if (mathcodeList.length > 0) {
        for (let i = 0; i < mathcodeList.length; i++) {
          if (mathcodeList[i].naturalWidth === 0 || mathcodeList[i].naturalHeight === 0) {
            var alt = mathcodeList[i].alt;
            alt = '\\(' + alt + '\\)';
            var curSpan = $('<span class="img-codecogs"></span>');
            curSpan.text(alt);
            $(mathcodeList[i]).before(curSpan);
            $(mathcodeList[i]).remove();
          }
        }
        MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
      }
    }, 1000)
  });
</script>
</div></html>